package com.gitee.wsl.prism4j.ui

import androidx.annotation.ColorInt
import androidx.annotation.ColorLong
import androidx.annotation.FloatRange
import androidx.annotation.IntRange
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import com.gitee.wsl.prism4j.Prism4j
import java.util.HashMap

abstract class Prism4jThemeBase protected constructor() : Prism4jTheme {
     open val colorHashMap: ColorHashMap = ColorHashMap()


    @ColorInt
    protected fun color(language: String, type: String, alias: String?): Long {
        var color = colorHashMap[type]
        if (color == null && alias != null) {
            color = colorHashMap[alias]
        }
        return color?.color ?: 0L
    }

    override fun apply(
        language: String,
        syntax: Prism4j.Syntax,
        builder:  AnnotatedString.Builder,
        start: Int,
        end: Int
    ) {
        val type = syntax.type()
        val alias = syntax.alias()
        val color = color(language, type, alias)
        if (color != 0L) {
            applyColor(language, type, alias, color, builder, start, end)
        }
    }

    protected open fun applyColor(
        language: String,
        type: String,
        alias: String?,
        @ColorInt color: Long,
        builder:AnnotatedString.Builder,
        start: Int,
        end: Int
    ) {
        builder.addStyle(
            SpanStyle(color = Color(color)),
            start = start,
            end = end
        )
        //builder.setSpan(ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    }



    open class Color protected constructor(@field:ColorInt @param:ColorInt val color: Long) {
        companion object {
            fun of(@ColorInt color: Long): Color {
                return Color(color)
            }
        }
    }

    class ColorHashMap : HashMap<String, Color>() {

        fun add(@ColorInt color: Long, vararg names: String): ColorHashMap {
            val c = Color.of(color)
            for (name in names) {
                put(name, c)
            }
            return this
        }
    }

    companion object {
        @ColorInt
        protected fun applyAlpha(
            @IntRange(from = 0, to = 255) alpha: Int,
            @ColorInt color: Long
        ): Long {
            return color and 0x00FFFFFF or ((alpha shl 24).toLong())
        }

        @JvmStatic
        @ColorInt
        protected fun applyAlpha(
            @FloatRange(from = 0.0, to = 1.0) alpha: Float,
            @ColorLong color: Long
        ): Long {
            return applyAlpha((255 * alpha + .5f), color)
        }

        @JvmStatic
        protected fun isOfType(expected: String, type: String, alias: String?): Boolean {
            return expected == type || expected == alias
        }
    }
}

fun AnnotatedString.Builder.strongEmphasis(start: Int, end: Int) {
    addStyle(SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic), start, end)
}

fun AnnotatedString.Builder.emphasis(start: Int, end: Int) {
    addStyle(SpanStyle(fontStyle = FontStyle.Italic), start, end)
}